package io.github.xbeeant.eoffice.util;

import io.github.xbeeant.eoffice.onlyoffice.OnlyOfficeConfiguration;
import io.github.xbeeant.spring.web.SpringContextProvider;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * @author xiaobiao
 * @version 2021/7/1
 */
public class FileHelper {
    private static final Logger logger = LoggerFactory.getLogger(FileHelper.class);

    public static String changesUrl(Long vid, String sessionId) {
        return SpringContextProvider.getBean(OnlyOfficeConfiguration.class).getServer() + "api/office/changes?vid=" + vid + "&token=" + SecurityHelper.jwtToken(sessionId);
    }

    public static String downloadUrl(Long rid, String sessionId) {
        return SpringContextProvider.getBean(OnlyOfficeConfiguration.class).getServer() + "api/office/download?rid=" + rid + "&token=" + SecurityHelper.jwtToken(sessionId);
    }

    public static String downloadUrl(Long rid, Long vid, String sessionId) {
        return SpringContextProvider.getBean(OnlyOfficeConfiguration.class).getServer() + "api/office/download?rid=" + rid + "&vid=" + vid + "&token=" + SecurityHelper.jwtToken(sessionId);
    }

    public static String extension(String filename) {
        int idx = filename.lastIndexOf(".");
        return filename.substring(idx + 1);
    }

    public static String md5(File file) throws NoSuchAlgorithmException {
        // instantiate a MessageDigest Object by passing
        // string "MD5" this means that this object will use
        // MD5 hashing algorithm to generate the checksum
        MessageDigest digest = MessageDigest.getInstance("MD5");

        // Get file input stream for reading the file
        // content
        try (FileInputStream fis = new FileInputStream(file);) {
            // Create byte array to read data in chunks
            byte[] byteArray = new byte[1024];
            int bytesCount = 0;

            // read the data from file and update that data in
            // the message digest
            while ((bytesCount = fis.read(byteArray)) != -1) {
                digest.update(byteArray, 0, bytesCount);
            }
        } catch (Exception e) {
            logger.error("文件读取异常", e);
        }

        // store the bytes returned by the digest() method
        byte[] bytes = digest.digest();

        // this array of bytes has bytes in decimal format
        // so we need to convert it into hexadecimal format

        // for this we create an object of StringBuilder
        // since it allows us to update the string i.e. its
        // mutable
        StringBuilder sb = new StringBuilder();

        // loop through the bytes array
        for (byte aByte : bytes) {
            // the following line converts the decimal into
            // hexadecimal format and appends that to the
            // StringBuilder object
            sb.append(Integer
                    .toString((aByte & 0xff) + 0x100, 16)
                    .substring(1));
        }

        // finally we return the complete hash
        return sb.toString();
    }

    public static String md5(MultipartFile upload) throws NoSuchAlgorithmException {
        // instantiate a MessageDigest Object by passing
        // string "MD5" this means that this object will use
        // MD5 hashing algorithm to generate the checksum
        MessageDigest digest = MessageDigest.getInstance("MD5");

        // Get file input stream for reading the file
        // content
        try (InputStream fis = upload.getInputStream();) {
            // Create byte array to read data in chunks
            byte[] byteArray = new byte[1024];
            int bytesCount = 0;

            // read the data from file and update that data in
            // the message digest
            while ((bytesCount = fis.read(byteArray)) != -1) {
                digest.update(byteArray, 0, bytesCount);
            }
        } catch (Exception e) {
            logger.error("文件读取异常", e);
        }

        // store the bytes returned by the digest() method
        byte[] bytes = digest.digest();

        // this array of bytes has bytes in decimal format
        // so we need to convert it into hexadecimal format

        // for this we create an object of StringBuilder
        // since it allows us to update the string i.e. its
        // mutable
        StringBuilder sb = new StringBuilder();

        // loop through the bytes array
        for (byte aByte : bytes) {
            // the following line converts the decimal into
            // hexadecimal format and appends that to the
            // StringBuilder object
            sb.append(Integer
                    .toString((aByte & 0xff) + 0x100, 16)
                    .substring(1));
        }

        // finally we return the complete hash
        return sb.toString();
    }

    public static void read(OutputStream outputStream, String filename) {
        OnlyOfficeConfiguration onlyOfficeConfiguration = SpringContextProvider.getBean(OnlyOfficeConfiguration.class);
        String storageFolder = onlyOfficeConfiguration.getStorageFolder();
        File file = new File(storageFolder + filename);
        logger.debug("读取文件 {}", filename);
        try (FileInputStream fileInputStream = new FileInputStream(file);) {
            IOUtils.copy(fileInputStream, outputStream);
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
    }
}
